#include <stdio.h>
#include <string.h>
#include <stdlib.h>

//Structure defined for each item, item has a name, a weight and a pointer to the next item that coems after it
struct item{
	char name[100]; // Name of item
	float weight;  // Items weight 
	struct item *next; //Next item if any in the list
};

//Each bin has a capacity and a pointer to a linked list items in the list
struct bin{
	float capacity; // Currently how free is the bin
	struct item *front; //Start of the list
};

//Prototypes
//Prototype for an input
struct bin input(struct bin, char[], float);
//Prototype for a destroy
struct bin destroy(struct bin);
//Prototype for a print
void print(struct bin[]);

void main(){
	//Name of item
	char name[10];
	//Weight of item
	float weight=1.001;
	//coutner for loop
	int counter;
	//Array of 10 bins
	struct bin arraybin[10];
	// Variable to jump out of loop after its been put into bin
	int found=0;

	//Initlizing all the bins there capacity to be 1 and their front pointers to be null
	for(counter = 0; counter < 10 ; counter++){
		arraybin[counter].front=NULL;
		arraybin[counter].capacity = weight;
	}

	// does loop till user press exit and -1
	do{
		//User prompt to input and input	
		printf("Please enter a item name followed by its weight or exit -1 to exit: ");
		scanf("%s %f", name, &weight);
		//Reinitlizing found so we can check to see if we should be thrown out of loop
		found=0;

		//checking to see if we should place user input in bin
		if(strcmp(name, "exit") != 0){
			//Loop to iterate through bin to check which bin to place it in
			for(counter = 0; (counter < 10) && (found==0); counter++)
			{
				//Checking if there is room in the bin to place item
				if(arraybin[counter].capacity >= weight)
				{
					//if there is reducing capcity
					arraybin[counter].capacity -= weight;
					
					//Placing item in the right spot for bin
					arraybin[counter] = input(arraybin[counter], name, weight);

					//Adjusting found so we can leave loop since item is already placed in bin
					found=1;
				}
			}
		}
	}while(strcmp(name, "exit") != 0); // Condition if user pressed quit exit out of input

	//Printing all the bins
	print(arraybin);

	//Loop to reinitlize your bins
	for(counter = 0; counter < 10; counter++){
		//Frees Memory
		arraybin[counter]=destroy(arraybin[counter]);
	}

	//printing bin after clearing memory and reintilizing the bins
	print(arraybin);

}

struct bin input(struct bin arraybin, char *name,float weight){
	//temp variable so we can test current and see where to place item
	struct item *temp = arraybin.front;

	//another temp variable so if next item is bigger then previous we can place right after previous
	struct item *previous = NULL;

	//Just a temp item to be able to readjust linked list in bin
	struct item *tempitem;
	
	//Checking if there are items in bin if not place item in the front of list
	if(temp == NULL)
	{
		// memory allocation for item in bin
		temp = malloc(sizeof(struct item));
		
		// Initlizing name of item into item struct 
		strcpy(temp->name,name);
		
		// Initlizing weight of item into item struct
		temp->weight = weight;

		//Initlizing next item in list to null
		temp->next = NULL;

		//Initlizing front to adr of temp so that list format is created
		arraybin.front=temp;

		//Retruning value
		return arraybin;
	}
	
	//Loop to see where to place in item alphabetically.
	while((temp != NULL) && (strcmp(name,temp->name) > 0 ) ){
		previous = temp;
		temp = temp->next;
	}

	//If condition to check if we need to place item at beginning of list
	if(previous == NULL)
	{
		//creating memory for item
		tempitem = malloc(sizeof(struct item));
		
		//Initlizing weight of item into item struct
		tempitem->weight = weight;
		
		//Initlizing name of item into item struct
		strcpy(tempitem->name,name);
		
		//Rearranging pointers so list is in correct order
		tempitem->next = temp;
		arraybin.front = tempitem;

		//returning bin
		return arraybin;
	}

	//creating memory for item if item goes somewhere in the middle or end of list
	tempitem = malloc(sizeof(struct item));

	//Initlizing weight in item struct
	tempitem->weight = weight;

	//Initlizing name in item struct
	strcpy(tempitem->name,name);

	//Rearranging pointers so list is in correct order
	tempitem->next = temp;
	previous->next = tempitem;

	//returning bin
	return arraybin;
		
	
	/**
	temp->next = malloc(sizeof(struct item));
	temp=temp->next;
	temp->next=NULL;
	strcpy(temp->name,name);
	temp->weight = weight;
	return arraybin;
	**/
}

struct bin destroy(struct bin arraybin){
	
	//temporary item so we can free that item
	struct item *temp = arraybin.front;

	//reinitlizing bin capacity
	arraybin.capacity = 1.001;

	//run loop till list is empty
	while(arraybin.front != NULL){
		//Take next item and place it as the first item
		arraybin.front = temp->next;

		//Free previous first item
		free(temp);

		//Reinitlize temp
		temp = arraybin.front;
	}
	//Return empty bin
	return arraybin;
	
}

//Printing the whole bin
void print(struct bin arraybin[10]){
	//temp item so to print through each item in bin
	struct item *temp;
	
	//temp variable for loop 
	int counter;

	//Run thorugh each bin
	for(counter = 0; counter < 10; counter++)
	{
		//Prininting bin no. and capacity of bin
		printf("\nBin no. %d has a ending capacity of %f .\n", counter, (arraybin[counter].capacity-0.001));

		//Printing list of items and their weights
		printf("The list of items in bin and their weights in parenthesis are as follows: ");
		
		//Initlizing temp to begining of list
		temp = arraybin[counter].front;

		//Run thorugh list
		while(temp != NULL){
			//Printing each item
			printf("%s(%3.2f) ",temp->name, temp->weight);

			//Continue to the next item... 
			temp = temp->next;
		}
	}
}